package com.hotec.PROJECT_NAME.utils;

import org.apache.commons.codec.binary.Base64;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.*;


/**
 * 功能描述：
 * 创建时间：Mar 9, 2009 11:18:04 AM
 *
 * @version 1.0
 */
@SuppressWarnings("all")
public class UtilsEncrypt {

    public static UtilsEncrypt getInstance() {
        return new UtilsEncrypt();
    }

    /**
     * 加密操作
     *
     * @param data
     * @return
     */
    public static String encrypt(String data, String secret) {
        byte[] enbytes = Base64.encodeBase64Chunked(simplecrypt(data, secret).getBytes());
        return new String(enbytes);
    }

    /**
     * 解密操作
     *
     * @param data
     * @return
     * @throws IOException
     */
    public static String decrypt(String data, String secret) {
        byte[] debytes = Base64.decodeBase64(new String(data).getBytes());
        return simplecrypt(new String(debytes), secret);
    }

    /**
     * 功能描述：进行常量异或
     *
     * @param
     * @return String
     * @version 1.0
     * @date Mar 9, 200911:44:02 AM
     */
    public static String simplecrypt(String data, String secret) {
        char[] a = data.toCharArray();
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < secret.length(); j++) {
                char c = secret.charAt(j);
                a[i] = (char) (a[i] ^ c);
            }
        }
        String s = new String(a);
        return s;
    }

    //转换加密工具类
    public static String MD5(String s) {
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        try {
            byte[] btInput = s.getBytes();
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            UtilsLog.log(UtilsEncrypt.class, e);
            return null;
        }
    }

    private static byte[] getSHA1Digest(String data) throws IOException {
        byte[] bytes = null;
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            bytes = md.digest(data.getBytes("UTF-8"));
        } catch (GeneralSecurityException gse) {
            throw new IOException(gse.getMessage());
        }
        return bytes;
    }

    /**
     * 二进制转十六进制字符串
     *
     * @param bytes
     * @return
     */
    private static String byte2hex(byte[] bytes) {
        StringBuilder sign = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                sign.append("0");
            }
            sign.append(hex.toUpperCase());
        }
        return sign.toString();
    }

    /**
     * 使用<code>secret</code>对paramValues按以下算法进行签名： <br/>
     * uppercase(hex(sha1(secretkey1value1key2value2...secret))
     *
     * @param paramValues 参数列表
     * @param secret
     * @return
     */
    public static String sign(HashMap<String, Object> paramValues, String secret) {
        return sign(paramValues, null, secret);
    }

    public static String sign(String param, String secret) {
        StringBuilder sb = new StringBuilder();
        sb.append(secret);
        sb.append(param);
        sb.append(secret);
        byte[] sha1Digest = new byte[0];
        try {
            sha1Digest = getSHA1Digest(sb.toString());
        } catch (IOException e) {
            UtilsLog.log(UtilsEncrypt.class, e);
            throw new RuntimeException("系统内部转换错误！");
        }
        return byte2hex(sha1Digest);
    }

    /**
     * 对paramValues进行签名，其中ignoreParamNames这些参数不参与签名
     *
     * @param paramValues
     * @param ignoreParamNames
     * @param secret
     * @return
     */
    public static String sign(Map<String, Object> paramValues, List<String> ignoreParamNames, String secret) {
        try {
            StringBuilder sb = new StringBuilder();
            List<String> paramNames = new ArrayList<String>(paramValues.size());
            paramNames.addAll(paramValues.keySet());
            if (ignoreParamNames != null && ignoreParamNames.size() > 0) {
                for (String ignoreParamName : ignoreParamNames) {
                    paramNames.remove(ignoreParamName);
                }
            }
            Collections.sort(paramNames);

            sb.append(secret);
            for (String paramName : paramNames) {
                sb.append(paramName).append(String.valueOf(paramValues.get(paramName)));
            }
            sb.append(secret);
            System.out.println(sb.toString());
            byte[] sha1Digest = getSHA1Digest(sb.toString());
            return byte2hex(sha1Digest);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

   
}
